import json
import os
from datetime import datetime


class Task:
    def __init__(self, content, priority="中", tag="其他", created_at=None):
        self.content = content
        self.priority = priority
        self.tag = tag
        self.created_at = created_at or datetime.now().strftime("%Y-%m-%d")
        self.started_at = None
        self.done_at = None
        self.reminder_time = None
        self.daily_reminder = False
        self.reminder_active = True
        self.sound_path = None  # 确保使用sound_path作为属性名

    def to_dict(self):
        return {
            "内容": self.content,
            "优先级": self.priority,
            "分类": self.tag,
            "创建时间": self.created_at,
            "开始时间": self.started_at,
            "完成时间": self.done_at,
            "提醒时间": self.reminder_time,
            "每日提醒": self.daily_reminder,
            "提醒状态": self.reminder_active,
            "声音路径": self.sound_path  # 确保保存sound_path而不是sound_file
        }

    @classmethod
    def from_dict(cls, data):
        task = cls(data["内容"], data.get("优先级", "中"), data.get("分类", "其他"), data.get("创建时间"))
        task.started_at = data.get("开始时间")
        task.done_at = data.get("完成时间")
        task.reminder_time = data.get("提醒时间")
        task.daily_reminder = data.get("每日提醒", False)
        task.reminder_active = data.get("提醒状态", True)
        task.sound_path = data.get("声音路径")  # 确保从字典加载sound_path
        return task


class TaskStorage:
    FILE_PATH = "tasks.json"

    @staticmethod
    def load_tasks():
        if os.path.exists(TaskStorage.FILE_PATH):
            try:
                with open(TaskStorage.FILE_PATH, "r", encoding="utf-8") as f:
                    return json.load(f)
            except Exception as e:
                print(f"加载任务失败: {e}")
        return {"todo": [], "doing": [], "done": []}

    @staticmethod
    def save_tasks(todo_items, doing_items, done_items):
        try:
            with open(TaskStorage.FILE_PATH, "w", encoding="utf-8") as f:
                json.dump(
                    {
                        "todo": [t.to_dict() for t in todo_items],
                        "doing": [t.to_dict() for t in doing_items],
                        "done": [t.to_dict() for t in done_items],
                    },
                    f,
                    ensure_ascii=False,
                    indent=4,
                )
        except Exception as e:
            print(f"保存任务失败: {e}")


class TaskManager:
    def __init__(self):
        self.todo_items = []
        self.doing_items = []
        self.done_items = []

    def load_tasks(self):
        data = TaskStorage.load_tasks()
        self.todo_items = [Task.from_dict(t) for t in data.get("todo", [])]
        self.doing_items = [Task.from_dict(t) for t in data.get("doing", [])]
        self.done_items = [Task.from_dict(t) for t in data.get("done", [])]

    def save_tasks(self):
        TaskStorage.save_tasks(self.todo_items, self.doing_items, self.done_items)

    def add_task(self, content):
        task = Task(content)
        self.todo_items.append(task)
        return task

    def move_to_doing(self, task):
        task.started_at = datetime.now().strftime("%Y-%m-%d %H:%M")
        self.doing_items.append(task)

    def delete_item(self, items, index):
        del items[index]


class ReminderManager:
    def __init__(self, app):
        self.app = app

    def check_reminders(self):
        now = datetime.now().strftime("%H:%M")
        current_date = datetime.now().strftime("%Y-%m-%d")

        for task in self.app.todo_items + self.app.doing_items + self.app.done_items:
            if (
                task.reminder_time
                and task.reminder_active
                and task.reminder_time == now
                and (task.daily_reminder or task.created_at == current_date)
            ):
                self.notify(task)

        self.app.root.after(60000, self.check_reminders)

    def notify(self, task):
        print(f"任务提醒: {task.content}")  # 模拟通知


class UIManager:
    def __init__(self, root, task_manager, reminder_manager):
        self.root = root
        self.task_manager = task_manager
        self.reminder_manager = reminder_manager
        self.setup_styles()
        self.create_menu()
        self.create_widgets()
        self.reminder_sound_path = None  # 默认蜂鸣器声音
        self.buzzer_active = False

    def create_widgets(self):
        # 创建主框架
        main_frame = ttk.Frame(self.root)
        main_frame.pack(fill="both", expand=True)

        # Todo 列表
        todo_frame = ttk.Frame(main_frame)
        todo_frame.pack(side="left", fill="both", expand=True)
        columns_todo = ("内容", "优先级", "分类", "创建时间")
        self.todo_tree = ttk.Treeview(todo_frame, show='headings', style="Todo.Treeview")
        self.setup_tree_columns(self.todo_tree, columns_todo)
        self.todo_tree.pack(fill="both", expand=True, padx=5, pady=5)
        # 绑定双击事件
        self.todo_tree.bind("<Double-1>", lambda e: self.create_reminder_dialog())

        # Doing 列表
        doing_frame = ttk.Frame(main_frame)
        doing_frame.pack(side="left", fill="both", expand=True)
        columns_doing = ("内容", "优先级", "分类", "开始时间")
        self.doing_tree = ttk.Treeview(doing_frame, show='headings', style="Doing.Treeview")
        self.setup_tree_columns(self.doing_tree, columns_doing)
        self.doing_tree.pack(fill="both", expand=True, padx=5, pady=5)

        # Done 列表
        done_frame = ttk.Frame(main_frame)
        done_frame.pack(side="left", fill="both", expand=True)
        columns_done = ("内容", "优先级", "分类", "完成时间")
        self.done_tree = ttk.Treeview(done_frame, show='headings', style="Done.Treeview")
        self.setup_tree_columns(self.done_tree, columns_done)
        self.done_tree.pack(fill="both", expand=True, padx=5, pady=5)

    def create_reminder_dialog(self):
        # 创建提醒设置对话框并添加音频路径选择和播放控制
        dialog = tk.Toplevel(self.root)
        dialog.title("选择提醒声音")
        dialog.geometry("400x200")

        sound_frame = ttk.Frame(dialog)
        sound_frame.pack(pady=10)

        self.sound_entry = ttk.Entry(sound_frame, width=30)
        self.sound_entry.pack(side=tk.LEFT, padx=5)

        def select_sound_file():
            file_path = filedialog.askopenfilename(filetypes=[("音频文件", "*.wav *.mp3")])
            if file_path:
                self.sound_entry.delete(0, tk.END)
                self.sound_entry.insert(0, file_path)
                self.reminder_sound_path = file_path

        ttk.Button(sound_frame, text="浏览...", command=select_sound_file).pack(side=tk.LEFT)

        control_frame = ttk.Frame(dialog)
        control_frame.pack(pady=10)

        # 修改播放按钮的command，直接使用self.sound_entry.get()获取当前路径
        ttk.Button(control_frame, text="播放", command=lambda: self.play_sound(self.sound_entry.get())).pack(
            side=tk.LEFT, padx=5)
        ttk.Button(control_frame, text="停止", command=self.stop_buzzer).pack(side=tk.LEFT, padx=5)
        ttk.Button(dialog, text="确定", command=dialog.destroy).pack(pady=10)

    def stop_buzzer(self):
        self.buzzer_active = False

    def play_sound(self, path=None):
        # 播放指定路径的声音文件或默认蜂鸣器声音
        # 优先使用传入的路径，如果没有则使用类属性中保存的路径
        sound_path = path if path else self.reminder_sound_path
        
        if sound_path and os.path.exists(sound_path):
            # 实现自定义声音播放逻辑
            try:
                import winsound
                winsound.PlaySound(sound_path, winsound.SND_FILENAME | winsound.SND_ASYNC)
                self.buzzer_active = False  # 确保蜂鸣器状态为关闭
            except Exception as e:
                print(f"播放音频失败: {e}")
                self.start_buzzer()
        else:
            # 使用蜂鸣器声音
            self.start_buzzer()
